package com.ftinc.scoop.util; import android.support.annotation.IdRes; import android.support.test.espresso.PerformException; import android.support.test.espresso.UiController; import android.support.test.espresso.ViewAction; import android.support.test.espresso.matcher.BoundedMatcher; import android.support.test.espresso.matcher.ViewMatchers; import android.support.test.espresso.util.HumanReadables; import android.support.test.internal.util.Checks; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.EditText; import android.widget.TextView; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.Matchers; /** * Created by dannyroa on 5/9/15. */ public class TestUtils { public static <VH extends RecyclerView.ViewHolder> ViewAction actionOnItemViewAtPosition(int position, @IdRes int viewId, ViewAction viewAction) { return new ActionOnItemViewAtPositionViewAction(position, viewId, viewAction); } private static final class ActionOnItemViewAtPositionViewAction<VH extends RecyclerView .ViewHolder> implements ViewAction { private final int position; private final ViewAction viewAction; private final int viewId; private ActionOnItemViewAtPositionViewAction(int position, @IdRes int viewId, ViewAction viewAction) { this.position = position; this.viewAction = viewAction; this.viewId = viewId; } public Matcher<View> getConstraints() { return Matchers.allOf(new Matcher[]{ ViewMatchers.isAssignableFrom(RecyclerView.class), ViewMatchers.isDisplayed() }); } public String getDescription() { return "actionOnItemAtPosition performing ViewAction: " + this.viewAction.getDescription() + " on item at position: " + this.position; } public void perform(UiController uiController, View view) { RecyclerView recyclerView = (RecyclerView) view; (new ScrollToPositionViewAction(this.position)).perform(uiController, view); uiController.loopMainThreadUntilIdle(); View targetView = recyclerView.getChildAt(this.position).findViewById(this.viewId); if (targetView == null) { throw (new PerformException.Builder()).withActionDescription(this.toString()) .withViewDescription( HumanReadables.describe(view)) .withCause(new IllegalStateException( "No view with id " + this.viewId + " found at position: " + this.position)) .build(); } else { this.viewAction.perform(uiController, targetView); } } } private static final class ScrollToPositionViewAction implements ViewAction { private final int position; private ScrollToPositionViewAction(int position) { this.position = position; } public Matcher<View> getConstraints() { return Matchers.allOf(new Matcher[]{ ViewMatchers.isAssignableFrom(RecyclerView.class), ViewMatchers.isDisplayed() }); } public String getDescription() { return "scroll RecyclerView to position: " + this.position; } public void perform(UiController uiController, View view) { RecyclerView recyclerView = (RecyclerView) view; recyclerView.scrollToPosition(this.position); } } public static RecyclerViewMatcher withRecyclerView(final int recyclerViewId) { return new RecyclerViewMatcher(recyclerViewId); } public static Matcher<View> withTextColor(final int color) { Checks.checkNotNull(color); return new BoundedMatcher<View, TextView>(TextView.class) { @Override public boolean matchesSafely(TextView warning) { return color == warning.getCurrentTextColor(); } @Override public void describeTo(Description description) { description.appendText("with text color: "); } }; } }